# -*- coding: utf-8 -*-
"""
Redis连接管理器
提供Redis连接池和基础操作方法
"""

import redis.asyncio as redis
from typing import Optional, Any, Union
from src.config import config
from src.utils.logger import app_logger as logger


class RedisManager:
    """Redis连接管理器"""
    
    def __init__(self):
        self.redis_pool: Optional[redis.ConnectionPool] = None
        self.redis: Optional[redis.Redis] = None
    
    async def init_redis(self) -> None:
        """初始化Redis连接池"""
        try:
            # 构建Redis连接URL
            redis_url = f"redis://"
            if config.REDIS_PASSWORD:
                redis_url += f":{config.REDIS_PASSWORD}@"
            redis_url += f"{config.REDIS_HOST}:{config.REDIS_PORT}/{config.REDIS_DB}"
            
            # 创建连接池
            self.redis_pool = redis.ConnectionPool.from_url(
                redis_url,
                max_connections=config.REDIS_MAX_CONNECTIONS,
                encoding="utf-8",
                decode_responses=True
            )
            
            # 创建Redis客户端
            self.redis = redis.Redis(connection_pool=self.redis_pool)
            
            # 测试连接
            await self.redis.ping()
            logger.info(f"Redis连接成功: {config.REDIS_HOST}:{config.REDIS_PORT}")
            
        except Exception as e:
            logger.error(f"Redis连接失败: {e}")
            raise
    
    async def close_redis(self) -> None:
        """关闭Redis连接"""
        if self.redis:
            await self.redis.close()
        if self.redis_pool:
            await self.redis_pool.disconnect()
        logger.info("Redis连接已关闭")
    
    async def get(self, key: str) -> Optional[str]:
        """获取键值"""
        if not self.redis:
            raise RuntimeError("Redis未初始化")
        return await self.redis.get(key)
    
    async def set(self, key: str, value: Any, ex: Optional[int] = None) -> bool:
        """设置键值"""
        if not self.redis:
            raise RuntimeError("Redis未初始化")
        return await self.redis.set(key, value, ex=ex)
    
    async def delete(self, *keys: str) -> int:
        """删除键"""
        if not self.redis:
            raise RuntimeError("Redis未初始化")
        return await self.redis.delete(*keys)
    
    async def exists(self, key: str) -> bool:
        """检查键是否存在"""
        if not self.redis:
            raise RuntimeError("Redis未初始化")
        return bool(await self.redis.exists(key))
    
    async def expire(self, key: str, time: int) -> bool:
        """设置键过期时间"""
        if not self.redis:
            raise RuntimeError("Redis未初始化")
        return await self.redis.expire(key, time)
    
    async def hget(self, name: str, key: str) -> Optional[str]:
        """获取哈希表字段值"""
        if not self.redis:
            raise RuntimeError("Redis未初始化")
        return await self.redis.hget(name, key)
    
    async def hset(self, name: str, key: str, value: Any) -> int:
        """设置哈希表字段值"""
        if not self.redis:
            raise RuntimeError("Redis未初始化")
        return await self.redis.hset(name, key, value)
    
    async def hgetall(self, name: str) -> dict:
        """获取哈希表所有字段"""
        if not self.redis:
            raise RuntimeError("Redis未初始化")
        return await self.redis.hgetall(name)
    
    async def incr(self, key: str, amount: int = 1) -> int:
        """递增计数器"""
        if not self.redis:
            raise RuntimeError("Redis未初始化")
        return await self.redis.incr(key, amount)
    
    async def decr(self, key: str, amount: int = 1) -> int:
        """递减计数器"""
        if not self.redis:
            raise RuntimeError("Redis未初始化")
        return await self.redis.decr(key, amount)


# 全局Redis管理器实例
redis_manager = RedisManager()


async def init_redis_with_app() -> None:
    """应用启动时初始化Redis"""
    await redis_manager.init_redis()


async def close_redis_with_app() -> None:
    """应用关闭时关闭Redis连接"""
    await redis_manager.close_redis()


def get_redis() -> RedisManager:
    """获取Redis管理器实例"""
    return redis_manager